package com.zidongxiangxi.rabbit.consumer.manager;

import com.zidongxiangxi.rabbit.consumer.sql.ConsumeRecordSqlProvider;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * RabbitMQ消费记录管理类
 *
 * @author chenxudong
 * @date 2020/11/07
 */
public class ConsumeRecordManager {
	private final ConsumeRecordSqlProvider sqlProvider;
	private final JdbcTemplate jdbcTemplate;
	private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;

	public ConsumeRecordManager(String tableName, JdbcTemplate jdbcTemplate) {
		this.sqlProvider = new ConsumeRecordSqlProvider(tableName);
		this.jdbcTemplate = jdbcTemplate;
		this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
	}

	public List<Long> listIds(Date beforeTime, int size) {
		return jdbcTemplate.queryForList(sqlProvider.getSelectIdSql(), Long.class, beforeTime, size);
	}

	public boolean isConsumed(String produceApplication, String consumeApplication, String messageId) {
		List<Integer> result = jdbcTemplate.queryForList(sqlProvider.getExistSql(), Integer.class, produceApplication,
				consumeApplication, messageId);
		return !CollectionUtils.isEmpty(result);
	}

	@Transactional(rollbackFor = Exception.class)
	public boolean saveRecord(String produceApplication, String consumeApplication, String messageId) {
		if (isConsumed(produceApplication, consumeApplication, messageId)) {
			return false;
		}
		try {
			return jdbcTemplate.update(sqlProvider.getInsertSql(), produceApplication, consumeApplication, messageId) > 0;
		} catch (DuplicateKeyException e) {
			return false;
		}
	}

	@Transactional(rollbackFor = Exception.class)
	public boolean deleteRecord(String produceApplication, String consumeApplication, String messageId) {
		int rows = jdbcTemplate.update(sqlProvider.getDeleteSql(), produceApplication, consumeApplication, messageId);
		return rows > 0;
	}

	@Transactional(rollbackFor = Exception.class)
	public boolean deleteRecords(List<Long> ids) {
		Map<String, Object> args = new HashMap<>(1);
		args.put("ids", ids);
		return namedParameterJdbcTemplate.update(sqlProvider.getBatchDeleteSql(), args) > 0;
	}
}
